Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a new FilterCard component with Section/Item/Footer subcomponents, documentation and playground examples; refactors DataTable UI to use FilterCard; adds Popover variant support including an unstyled option; adjusts related CSS and exports across the codebase. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (3)
packages/raystack/components/popover/popover.module.css (1)
22-26: Consider extracting shared resets into a base/composed class.
outline: 0andbox-sizing: border-boxare duplicated between.popoverand.popoverUnstyled. Extracting them into a shared base class (e.g.,.popoverBase) and composing in both would eliminate the repetition.♻️ Proposed refactor
+.popoverBase { + outline: 0; + box-sizing: border-box; + animation: slideUpAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1); +} + .popover { - outline: 0; overflow: hidden; font-size: var(--rs-font-size-small); line-height: var(--rs-line-height-small); letter-spacing: var(--rs-letter-spacing-small); - box-sizing: border-box; min-width: 120px; max-width: 18rem; padding: var(--rs-space-3); background-color: var(--rs-color-background-base-primary); border-radius: var(--rs-radius-2); box-shadow: var(--rs-shadow-soft); border: 1px solid var(--rs-color-border-base-primary); color: var(--rs-color-foreground-base-primary); - animation: slideUpAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1); } .popoverUnstyled { - outline: 0; - box-sizing: border-box; - animation: slideUpAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1); }Then in
popover.tsx, compose the base class viacva:const popover = cva(styles.popoverBase, { variants: { variant: { - default: styles.popover, + default: styles.popover, // adds visual tokens on top of base unstyled: styles.popoverUnstyled } },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/raystack/components/popover/popover.module.css` around lines 22 - 26, Duplicate resets (outline: 0 and box-sizing: border-box) exist in .popover and .popoverUnstyled; extract them into a shared CSS class (e.g., .popoverBase) in popover.module.css and remove the duplicates from both existing classes, then update popover.tsx to compose .popoverBase with the existing classes (use the cva composition or class merging used in the component) so both .popover and .popoverUnstyled include the shared base styling.apps/www/src/content/docs/components/filter-card/props.ts (2)
52-61:FilterCardItemPropsin docs is narrower than the actual component interface.The real implementation (
filter-card-item.tsx) declares:export interface FilterCardItemProps extends HTMLAttributes<HTMLDivElement> { label: string; }It inherits
children,className,onClick,style, and all other HTML div attributes fromHTMLAttributes. The docs interface only exposeslabel,children?, andclassName?, silently omitting the rest of the passthrough surface. Consider extendingHTMLAttributes<HTMLDivElement>(or at least noting the omission) to keep the docs aligned with the actual API.♻️ Proposed alignment
+import type { HTMLAttributes } from 'react'; + -export interface FilterCardItemProps { +export interface FilterCardItemProps extends HTMLAttributes<HTMLDivElement> { /** Label text displayed on the left */ label: string; - - /** Action content displayed on the right */ - children?: React.ReactNode; - - /** Additional CSS class names */ - className?: string; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/www/src/content/docs/components/filter-card/props.ts` around lines 52 - 61, The docs interface FilterCardItemProps is too narrow compared to the real component (see filter-card-item.tsx); update the docs declaration to extend HTMLAttributes<HTMLDivElement> so it includes children, className, onClick, style and other passthrough div attributes (i.e., make FilterCardItemProps extend HTMLAttributes<HTMLDivElement> to align the docs with the implementation).
1-7: Add explicit React import forReact.ReactNode.
React.ReactNodeis used across all four interfaces in this.tsfile without importingReact. While the code likely compiles due to implicit type resolution, this pattern is inconsistent with best practices observed elsewhere in the codebase (e.g.,breadcrumb,code-block,datatableprops files explicitly import React types). Adding an explicit import makes the dependency clear and avoids relying on implicit resolution.♻️ Proposed fix
+import type { ReactNode } from 'react'; + export interface FilterCardProps { /** Content of the filter card */ - children?: React.ReactNode; + children?: ReactNode; /** Additional CSS class names */ className?: string; } export interface FilterCardSectionProps { /** Optional title for the section */ title?: string; /** Content of the section */ - children?: React.ReactNode; + children?: ReactNode; ... } export interface FilterCardItemProps { /** Label text displayed on the left */ label: string; /** Action content displayed on the right */ - children?: React.ReactNode; + children?: ReactNode; ... } export interface FilterCardFooterProps { /** Content of the footer */ - children?: React.ReactNode; + children?: ReactNode; ... }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/www/src/content/docs/components/filter-card/props.ts` around lines 1 - 7, Add an explicit type-only React import at the top of the file so the uses of React.ReactNode in FilterCardProps (and the other three interfaces in this file) are resolved explicitly; e.g., add "import type * as React from 'react'" (type-only to avoid runtime import), keep the existing React.ReactNode type annotations in FilterCardProps and the other interfaces unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/www/src/components/playground/filter-card-examples.tsx`:
- Around line 47-50: The playground's Reset button in FilterCard.Footer uses
Button with variant='ghost' which doesn't match the real usage; update the
Button in FilterCard.Footer (in filter-card-examples.tsx) to use variant='text'
and add color='neutral' so it matches the Reset to default button implementation
used in display-settings (the same "Reset to default" action).
- Around line 13-16: Remove the invalid variant on the select trigger: delete
variant='filter' from Select.Trigger instances and, if filter styling is needed,
add data-variant='filter' to the corresponding Select.Content component (match
how ordering.tsx/grouping.tsx do it). Also change the reset Button from
variant='ghost' to variant='text' and add color='neutral' so the playground
matches display-settings.tsx's reset button pattern. Ensure you update both
occurrences noted around Select.Trigger (the two triggers) and the reset Button
instance.
In `@apps/www/src/content/docs/components/filter-card/demo.ts`:
- Around line 5-10: getCode currently interpolates children verbatim into the
template string which can break generated JSX if users enter characters like <,
>, ${, or backticks; update getCode to escape/sanitize children before
interpolation (e.g., replace &, <, >, ", ', ${ and backticks with safe
equivalents) so the returned string always produces valid JSX, use the sanitized
version inside the
<FilterCard.Section${getPropsString(rest)}>...</FilterCard.Section> output, and
while here replace props: any with the proper typed interface exported from
props.ts (e.g., FilterCardProps or the correct name) so destructuring {
children, ...rest } is type-checked.
In `@packages/raystack/components/popover/popover.tsx`:
- Around line 20-26: The docs interface for the Popover props is missing the
variant prop, so update the exported documentation type to include
VariantProps<typeof popover> (or explicitly add a variant?: string union
matching popover) so the prop-table shows it; specifically ensure the docs'
PopoverContentProps (the docs equivalent of the component type) mirrors the
component's PopoverContentProps which extends VariantProps<typeof popover> so
the variant prop is documented and exposed in the playground.
---
Nitpick comments:
In `@apps/www/src/content/docs/components/filter-card/props.ts`:
- Around line 52-61: The docs interface FilterCardItemProps is too narrow
compared to the real component (see filter-card-item.tsx); update the docs
declaration to extend HTMLAttributes<HTMLDivElement> so it includes children,
className, onClick, style and other passthrough div attributes (i.e., make
FilterCardItemProps extend HTMLAttributes<HTMLDivElement> to align the docs with
the implementation).
- Around line 1-7: Add an explicit type-only React import at the top of the file
so the uses of React.ReactNode in FilterCardProps (and the other three
interfaces in this file) are resolved explicitly; e.g., add "import type * as
React from 'react'" (type-only to avoid runtime import), keep the existing
React.ReactNode type annotations in FilterCardProps and the other interfaces
unchanged.
In `@packages/raystack/components/popover/popover.module.css`:
- Around line 22-26: Duplicate resets (outline: 0 and box-sizing: border-box)
exist in .popover and .popoverUnstyled; extract them into a shared CSS class
(e.g., .popoverBase) in popover.module.css and remove the duplicates from both
existing classes, then update popover.tsx to compose .popoverBase with the
existing classes (use the cva composition or class merging used in the
component) so both .popover and .popoverUnstyled include the shared base
styling.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (20)
apps/www/src/components/playground/filter-card-examples.tsxapps/www/src/components/playground/index.tsapps/www/src/content/docs/components/filter-card/demo.tsapps/www/src/content/docs/components/filter-card/index.mdxapps/www/src/content/docs/components/filter-card/props.tspackages/raystack/components/data-table/components/display-properties.tsxpackages/raystack/components/data-table/components/display-settings.tsxpackages/raystack/components/data-table/components/grouping.tsxpackages/raystack/components/data-table/components/ordering.tsxpackages/raystack/components/data-table/data-table.module.csspackages/raystack/components/filter-card/filter-card-footer.tsxpackages/raystack/components/filter-card/filter-card-item.tsxpackages/raystack/components/filter-card/filter-card-root.tsxpackages/raystack/components/filter-card/filter-card-section.tsxpackages/raystack/components/filter-card/filter-card.module.csspackages/raystack/components/filter-card/filter-card.tsxpackages/raystack/components/filter-card/index.tsxpackages/raystack/components/popover/popover.module.csspackages/raystack/components/popover/popover.tsxpackages/raystack/index.tsx
| <Select.Trigger | ||
| size='small' | ||
| variant='filter' | ||
| style={{ width: '100%' }} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find the Select component definition and check for variant support
find . -type f -path "*select*" -name "*.tsx" -o -name "*.ts" | head -20Repository: raystack/apsara
Length of output: 931
🏁 Script executed:
#!/bin/bash
# Search for SelectTrigger or Select.Trigger component definition
rg -n "SelectTrigger|type.*Trigger.*Props|interface.*Trigger.*Props" --type=tsx --type=ts -A5 | head -100Repository: raystack/apsara
Length of output: 86
🏁 Script executed:
#!/bin/bash
# Check the actual filter-card-examples.tsx file at the lines mentioned
cat -n apps/www/src/components/playground/filter-card-examples.tsx | sed -n '1,60p'Repository: raystack/apsara
Length of output: 2303
🏁 Script executed:
#!/bin/bash
# Check ordering.tsx for Select usage pattern
cat -n apps/www/src/components/playground/ordering.tsx | sed -n '35,55p'Repository: raystack/apsara
Length of output: 138
🏁 Script executed:
#!/bin/bash
# Check display-settings.tsx for Button variant on Reset button
cat -n apps/www/src/components/playground/display-settings.tsx | sed -n '100,115p'Repository: raystack/apsara
Length of output: 146
🏁 Script executed:
#!/bin/bash
# Search for ordering.tsx and display-settings.tsx across the repo
fd "ordering.tsx|display-settings.tsx" .Repository: raystack/apsara
Length of output: 198
🏁 Script executed:
#!/bin/bash
# Find Select component source files
fd "select" packages/raystack/components/ -type f | head -20Repository: raystack/apsara
Length of output: 229
🏁 Script executed:
#!/bin/bash
# Look for Select component definition and check variant prop
rg "variant.*filter" --type ts --type tsx -B3 -A3 | head -80Repository: raystack/apsara
Length of output: 86
🏁 Script executed:
#!/bin/bash
# Search for Select.Trigger or SelectTrigger component definition
rg "Select\.Trigger|SelectTrigger" --type ts --type tsx -B2 -A8 | head -120Repository: raystack/apsara
Length of output: 86
🏁 Script executed:
#!/bin/bash
# Read ordering.tsx from correct path
cat -n packages/raystack/components/data-table/components/ordering.tsx | head -60Repository: raystack/apsara
Length of output: 2254
🏁 Script executed:
#!/bin/bash
# Read display-settings.tsx from correct path
cat -n packages/raystack/components/data-table/components/display-settings.tsx | head -120Repository: raystack/apsara
Length of output: 3701
🏁 Script executed:
#!/bin/bash
# Find Select component source
find packages/raystack/components/select -type f -name "*.tsx" -o -name "*.ts" | head -20Repository: raystack/apsara
Length of output: 638
🏁 Script executed:
#!/bin/bash
# Read Select.Trigger component definition
cat -n packages/raystack/components/select/select-trigger.tsxRepository: raystack/apsara
Length of output: 2715
🏁 Script executed:
#!/bin/bash
# Read Select types to see what props are allowed
cat -n packages/raystack/components/select/types.tsRepository: raystack/apsara
Length of output: 238
Remove variant='filter' from Select.Trigger.
Select.Trigger only supports variant='outline' (default) or variant='text'. The value 'filter' is not a valid variant and will be ignored. In actual DataTable implementations (ordering.tsx, grouping.tsx), the filter styling is applied via data-variant='filter' on Select.Content, not on the trigger. Move or remove this prop from lines 15 and 31.
Align Button variant with actual implementation.
Line 48 uses variant='ghost', but the reset button in the actual DisplaySettings component (display-settings.tsx line 107) uses variant='text' color='neutral'. Align the playground example with the production pattern.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/www/src/components/playground/filter-card-examples.tsx` around lines 13
- 16, Remove the invalid variant on the select trigger: delete variant='filter'
from Select.Trigger instances and, if filter styling is needed, add
data-variant='filter' to the corresponding Select.Content component (match how
ordering.tsx/grouping.tsx do it). Also change the reset Button from
variant='ghost' to variant='text' and add color='neutral' so the playground
matches display-settings.tsx's reset button pattern. Ensure you update both
occurrences noted around Select.Trigger (the two triggers) and the reset Button
instance.
| export const getCode = (props: any) => { | ||
| const { children, ...rest } = props; | ||
| return `<FilterCard> | ||
| <FilterCard.Section${getPropsString(rest)}>${children}</FilterCard.Section> | ||
| </FilterCard>`; | ||
| }; |
There was a problem hiding this comment.
Unescaped children interpolation can produce malformed JSX output.
children is inserted verbatim into the JSX template string. If a playground user types characters like <, >, ${, or `, the generated code snippet will be syntactically broken. A minimal guard (e.g., HTML-entity escaping or clamping to alphanumeric input) keeps the output valid regardless of playground input.
Additionally, since props.ts introduces typed interfaces for FilterCard, consider replacing props: any with the appropriate type to get compile-time safety on the destructuring.
🛡️ Proposed fix
-export const getCode = (props: any) => {
+export const getCode = (props: { title?: string; children?: string }) => {
const { children, ...rest } = props;
+ const safeChildren = (children ?? '').replace(/</g, '<').replace(/>/g, '>');
return `<FilterCard>
- <FilterCard.Section${getPropsString(rest)}>${children}</FilterCard.Section>
+ <FilterCard.Section${getPropsString(rest)}>${safeChildren}</FilterCard.Section>
</FilterCard>`;
};🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/www/src/content/docs/components/filter-card/demo.ts` around lines 5 -
10, getCode currently interpolates children verbatim into the template string
which can break generated JSX if users enter characters like <, >, ${, or
backticks; update getCode to escape/sanitize children before interpolation
(e.g., replace &, <, >, ", ', ${ and backticks with safe equivalents) so the
returned string always produces valid JSX, use the sanitized version inside the
<FilterCard.Section${getPropsString(rest)}>...</FilterCard.Section> output, and
while here replace props: any with the proper typed interface exported from
props.ts (e.g., FilterCardProps or the correct name) so destructuring {
children, ...rest } is type-checked.
| export interface PopoverContentProps | ||
| extends Omit< | ||
| PopoverPrimitive.Positioner.Props, | ||
| 'render' | 'className' | 'style' | ||
| >, | ||
| PopoverPrimitive.Popup.Props {} | ||
| PopoverPrimitive.Popup.Props, | ||
| VariantProps<typeof popover> {} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, verify the docs PopoverContentProps interface does not include a variant prop
rg -n "variant" --type=ts apps/www/src/content/docs/components/popover/props.tsRepository: raystack/apsara
Length of output: 41
🏁 Script executed:
# Also check the actual component file to confirm variant is present
rg -n "variant" --type=ts packages/raystack/components/popover/popover.tsxRepository: raystack/apsara
Length of output: 195
🏁 Script executed:
# Read the docs props file to see the full PopoverContentProps interface
cat -n apps/www/src/content/docs/components/popover/props.tsRepository: raystack/apsara
Length of output: 2062
🏁 Script executed:
# Read the component file around lines 20-26 to see the actual interface
sed -n '15,30p' packages/raystack/components/popover/popover.tsxRepository: raystack/apsara
Length of output: 424
Docs PopoverContentProps interface is missing the variant prop.
The documentation interface in apps/www/src/content/docs/components/popover/props.ts doesn't include the variant prop that is available in the actual component (via VariantProps<typeof popover>). This causes the playground/prop-table to omit it, leaving consumers unaware the option exists.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/raystack/components/popover/popover.tsx` around lines 20 - 26, The
docs interface for the Popover props is missing the variant prop, so update the
exported documentation type to include VariantProps<typeof popover> (or
explicitly add a variant?: string union matching popover) so the prop-table
shows it; specifically ensure the docs' PopoverContentProps (the docs equivalent
of the component type) mirrors the component's PopoverContentProps which extends
VariantProps<typeof popover> so the variant prop is documented and exposed in
the playground.
- Fix invalid variant='filter' on Select.Trigger in examples - Align reset Button to variant='text' color='neutral' - Add variant prop to Popover docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
FilterCardcomponent withSection,Item, andFootersub-componentsunstyledvariant toPopover.Contentvia CVAFilterCardTest plan
/docs/components/filter-cardunstyledvariant works as expected🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Refactor
Documentation
Style